package com.magold.game;

import org.andengine.engine.camera.Camera;
import org.andengine.entity.IEntity;
import org.andengine.entity.modifier.IEntityModifier;
import org.andengine.entity.scene.menu.MenuScene;
import org.andengine.entity.scene.menu.animator.IMenuAnimator;
import org.andengine.entity.scene.menu.item.IMenuItem;
import org.andengine.util.modifier.IModifier;
import org.andengine.util.modifier.IModifier.IModifierListener;

public abstract class BaseTextMenu extends MenuScene {
	private boolean mBacking;
	private BackModifierFactory mModifierFactory;
	
	public BaseTextMenu(Camera pCamera, IMenuAnimator pAnimator, BackModifierFactory pModifierFactory) {
		super(pCamera);
		if (pAnimator != null) setMenuAnimator(pAnimator);
		mModifierFactory = pModifierFactory;
	}

	public BaseTextMenu() {
	}
	
	protected void onBeginBack() {}
	protected void onFinishBack() {}
	
	protected void registerModifierSafely(IMenuItem pMenuItem, IEntityModifier pModifier) {
		pMenuItem.unregisterEntityModifier(pModifier);
		pModifier.reset();
		pMenuItem.registerEntityModifier(pModifier);
	}
	
	public boolean isBacking() {
		return mBacking;
	}
	
	@Override
	public void back() {
		if (hasChildScene()) {
			getChildScene().back();
			return;
		}
		
		if (mBacking) return;
		
		beginBack();
		if (mModifierFactory == null) {
			super.back();
			return;
		}
		
		IEntityModifier last = null;
		for (IMenuItem item : mMenuItems) {
			IEntityModifier mod = mModifierFactory.getBackModifier(item);
			if (mod != null) item.registerEntityModifier(mod);
			last = mod;
		}
		
		if (last != null) {
			last.addModifierListener(new IModifierListener<IEntity>() {
				@Override
				public void onModifierStarted(IModifier<IEntity> pModifier, IEntity pItem) {
				}
				
				@Override
				public void onModifierFinished(IModifier<IEntity> pModifier, IEntity pItem) {
					pItem.unregisterEntityModifier((IEntityModifier) pModifier);
					BaseTextMenu.super.back();
					finishBack();
				}
			});
		} else {
			super.back();
			finishBack();
		}
	}
	
	private void beginBack() {
		mBacking = true;
		onBeginBack();
	}
	
	private void finishBack() {
		mBacking = false;
		onFinishBack();
	}

	public boolean hasParentScene() {
		return mParentScene != null;
	}
	
	public static interface BackModifierFactory {
		public IEntityModifier getBackModifier(IMenuItem pMenuItem);
	}
}
